﻿using MaterialDesignThemes.Wpf;
using RestSharp.Extensions;
using RPAVIEW.util;
using RPAVIEW.views.EditPage;
using RPAVIEW.views.EditPage.flows;
using RPAVIEW.views.HomePages;
using SUNRPA.CONTROLS.IMPL.domain.attrubutes;
using SUNRPA.CONTROLS.IMPL.domain.constant;
using SUNRPA.CONTROLS.IMPL.domain.flowRunningVar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace RPAVIEW.views.controlLibrary {
    /// <summary>
    /// SelVarTextBox.xaml 的交互逻辑
    /// </summary>
    public partial class SelVarTextBox:UserControl {
        private string hint;

        public static readonly DependencyProperty text = DependencyProperty.Register(
            "Text",
            typeof(string),
            typeof(SelVarTextBox),
            new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));
        public string Text{
            get { return (string)GetValue(text);}
            set { SetValue(text, value);}
        }

        public Binding TextBind{
            set { 
                this.SetBinding(text, value); 
            }
        }

        public string Hint { get => hint; set => hint = value; }

        public SelVarTextBox() {
            InitializeComponent();
            this.varTree.DataContext = this;
        }

        private void OpenVarTree(object sender, RoutedEventArgs e) {
            if(varTree.Visibility.Equals(Visibility.Collapsed)) { 
                varTree.Visibility = Visibility.Visible;
            } else { 
                varTree.Visibility = Visibility.Collapsed;
            }
        }

        private void VisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
            if(varTree.Visibility.Equals(Visibility.Visible)) { 
                //加载变量列表
                var varContext = ParamUtil.GetGlobalData();
                ConcurrentDictionary<string, RPAVariableDefineWrapper> runnVar = varContext[DefaultContents.RUNNING_PARAM];
                ConcurrentDictionary<string, RPAVariableDefineWrapper> globalVar = varContext[DefaultContents.GLOBLE_PARAM];
                List<VarTreeNode>? tree = new List<VarTreeNode>();
                AddTreeNode(tree, runnVar, true);
                AddTreeNode(tree, globalVar, false);
                varTree.treeView.ItemsSource = tree;
                varTree.OriginalTree = tree;
            }
        }

        private void AddTreeNode(List<VarTreeNode>? tree, ConcurrentDictionary<string, RPAVariableDefineWrapper> vars, bool needScopeJudge) {
            int currentIndex = -1;
            if(needScopeJudge) { 
                //变量是运行中变量，需要判断变量的作用域是否符合条件，符合条件才可以加到树中供用户选择
                //获取当前流程项可以选择的所有变量的索引
                EditHome editHome = WindowUtil.GetCurrentEditHome();
                currentIndex = editHome.FlowItems.Children.Count;
                FlowEditWindow editWindow = WindowUtil.GetWindow<FlowEditWindow>();
                if(editWindow.EditIndex >= 0) { 
                    currentIndex = editWindow.EditIndex;
                }else if(editWindow.InsertIndex >= 0) { 
                    currentIndex = editWindow.InsertIndex;
                }
            }
            foreach(string key in vars.Keys) { 
                RPAVariableDefineWrapper rpaDefineVar = vars[key];
                if(needScopeJudge) { 
                    if(rpaDefineVar.FlowItem == null || rpaDefineVar.FlowItem.Index >= currentIndex) { 
                       continue; 
                    }
                }
                Type varType = rpaDefineVar.VarType;
                ClassInfoAttribute attr = varType.GetAttribute<ClassInfoAttribute>();
                if(attr != null) { 
                    string classTypeName = attr.ClassTypeName;
                    VarTreeNode node = new VarTreeNode($"{key}({classTypeName})", varType, key);
                    tree.Add(node);
                    MemberInfo[] mis = varType.GetMembers();
                    foreach(MemberInfo mi in mis) { 
                        VariableMemberInfoAttribute varInfoAttr = mi.GetAttribute<VariableMemberInfoAttribute>();
                        if(varInfoAttr != null) { 
                            VarTreeNode subNode = new VarTreeNode($"{varInfoAttr.MemberName}", mi, key, varInfoAttr.Expression);
                            node.SubNodes.Add(subNode);
                        }
                    }
                }
            }
        }

        private void TextBoxLoaded(object sender, RoutedEventArgs e) {
            if(!string.IsNullOrEmpty(Hint)) { 
                HintAssist.SetHint(this.varNameBox, Hint);
            }
        }
    }
}
